package rfBio;

public class fasta_seq {

	// private data fields
	private String tag;
	private String seq;
	private String type;
	
	// interface methods
	
	public void set_tag(String s){
		tag = s;
	}
	
	public void set_seq(String s){
		seq = s;
	}
	
	public boolean set_type(String s){
		if( s.equals("p") || s.equals("P") ){
			type = "p";
			return true;
			
		}
		
		if( s.equals("d") || s.equals("D") ){
			type = "d";
			return true;
		}
		
		if( s.equals("r") || s.equals("R") ){
			type = "r";
			return true;
		}
		return false;
	}
	
	public String get_tag(){
		return tag;
	}
	
	public String get_seq(){
		return seq;
	}
	
	public String get_type(){
		return type;
	}
	
	// constructors
	
	public fasta_seq(){
		tag = "";
		seq = "";
	}
	
	//copy constructor
	public fasta_seq( fasta_seq f){
		tag = f.get_tag();
		seq = f.get_seq();
		type = f.get_type();
	}
	
	public fasta_seq(String t, String s){
		tag = t;
		seq = s;
		type = "p";
	}
	
	public fasta_seq(String t, String s, String tp){
		tag = t;
		seq = s;
		type = tp;
	}
	
	// to string
	public String toString(){
		return '>' + tag + '\n' + seq;
	}
	
	// methods
	
	public int length(){
		return seq.length();
	}
	
	public boolean isProtein(){
		if(type.equals("p")){
			return true;
		}
		else{
			return false;
		}
	}
	
	public boolean isRna(){
		if(type.equals("r")){
			return true;
		}
		else{
			return false;
		}
	}
	
	public boolean isDna(){
		//System.out.println("type is " + type);
		if(type.equals("d")){
			return true;
		}
		else{
			return false;
		}
	}
	
	public String get_residue(int i){
		//System.out.println(seq.substring(i, i+1));
		return seq.substring(i, i+1);
	}
	
	public void add(String s){
		seq = seq + s;
	}
	
	public fasta_seq reverse(){
		fasta_seq temp_f = new fasta_seq();
		String s = seq;
		int j = 0;
		
		temp_f.set_tag(tag);
		temp_f.set_type(type);
		
		if(this.isDna()){
			for(int i = s.length()-1; i >= 0 ; i--)
			{
				temp_f.add(get_residue(i));
			}
		}
		return temp_f;
	}
	
	public fasta_seq complement(){
		fasta_seq temp_f = new fasta_seq();
		String s = seq;
		int j = 0;
		
		temp_f.set_tag(tag);
		temp_f.set_type(type);
		
		if(this.isDna()){
			for(int i = 0; i < s.length() ; i++)
			{
				if(get_residue(i).equals("a")){
					temp_f.add("t");
				}
				if(get_residue(i).equals("A")){
					temp_f.add("T");
				}
				if(get_residue(i).equals("g")){
					temp_f.add("c");
				}
				if(get_residue(i).equals("G")){
					temp_f.add("C");
				}
				if(get_residue(i).equals("t")){
					temp_f.add("a");
				}
				if(get_residue(i).equals("T")){
					temp_f.add("A");
				}
				if(get_residue(i).equals("c")){
					temp_f.add("g");
				}
				if(get_residue(i).equals("C")){
					temp_f.add("G");
				}
				if(get_residue(i).equals("n")){
					temp_f.add("n");
				}
				if(get_residue(i).equals("N")){
					temp_f.add("N");
				}
			}
		}
		return temp_f;
	}
	
	public fasta_seq reverse_complement(){
		fasta_seq temp_f = new fasta_seq(tag, seq, type);		
		fasta_seq temp_f2 = new fasta_seq(temp_f.reverse());
		fasta_seq temp_f3 = new fasta_seq(temp_f2.complement());
		return temp_f3;				
	}
	
	public fasta_seq translate(int frame){
		
		String s = seq;
		String temp = seq;
		fasta_seq temp_f = new fasta_seq(tag + "_translated", "", "p"); 
		
		if( (frame < 0) || (frame > 2) ){
			return temp_f;
		}
		
		//trim end until divideble with 3
		
		s = s + "nnnnnn";
		
		/*if(frame != 0){
			while(s.length() % (3-(3-frame)) != 0){
				s = s + "n";
			}
		}
		else
		{
			while(s.length() % 3 != 0){
				s = s + "n";
			}
		}*/
		
		
		//translate
		
		if(this.isDna()){
			for(int i = frame; i < s.length() - frame-4; i = i+3 ){
				temp_f.add(Bioutil.DNAcodonToAA(s.substring(i,i+3)));
			}
		}
		
		return temp_f;
	}
	
	public fasta_seq get_longest_orf(){
		
		int start = 0, start_longest = 0, stop = 0, stop_longest = 0, longest_frame = 0;
		boolean inFrame = false;
		boolean stopFound = false;

		
		fasta_seq temp_f0 = new fasta_seq(this.translate(0));
		fasta_seq temp_f1 = new fasta_seq(this.translate(1));
		fasta_seq temp_f2 = new fasta_seq(this.translate(2));
		fasta_seq rc = new fasta_seq(this.reverse_complement());
		fasta_seq temp_f3 = new fasta_seq(rc.translate(0));
		fasta_seq temp_f4 = new fasta_seq(rc.translate(1));
		fasta_seq temp_f5 = new fasta_seq(rc.translate(2));
		fasta_seq return_seq = new fasta_seq(tag, "", "p");
		
		String s0;
		String s1;
		String s2;
		String s3;
		String s4;
		String s5;
		String curr_aa ="";
		
		//frame 0
		s0 = temp_f0.get_seq();	
		for(int i = 0; i < s0.length(); i++){
			curr_aa = s0.substring(i, i+1);

			if( (curr_aa.equalsIgnoreCase("m")) && !inFrame){
				start=i;
				inFrame = true;
				stopFound = false;

			}
			if( (curr_aa.equals(".")) && inFrame ){
				stop=i;
				inFrame = false;
				stopFound = true;

			}
			if(!inFrame && stopFound){
				if( (stop - start) > (stop_longest - start_longest) ){
					stop_longest = stop;
					start_longest = start;
					longest_frame = 0;
					
				}
				inFrame = false;
				stopFound = false;
			}
			
		}
		
		if(!stopFound && inFrame && ((s0.length() - 1 - start) > (stop_longest - start_longest))){
			stop_longest = s0.length() - 1;
			start_longest = start;
			longest_frame = 0;
		}
		//System.out.println(stop_longest - start_longest);
		//frame 1
		s1 = temp_f1.get_seq();
		curr_aa = "";
		inFrame = false;
		stopFound = false;	
		for(int i = 0; i < s1.length(); i++){
			curr_aa = s1.substring(i, i+1);
			if( (curr_aa.equalsIgnoreCase("m")) && !inFrame){
				start=i;
				inFrame = true;
				stopFound = false;
			}
			if( (curr_aa.equals(".")) && inFrame ){
				stop=i;
				inFrame = false;
				stopFound = true;
			}
			if(!inFrame && stopFound){
				if( (stop - start) > (stop_longest - start_longest) ){
					stop_longest = stop;
					start_longest = start;
					longest_frame = 1;
					//System.out.println("d1");
				}
				inFrame = false;
				stopFound = false;
			}
			
		}
		//System.out.println(start);
		//System.out.println(stop);
		if(!stopFound && inFrame && ((s1.length() - 1 - start) > (stop_longest - start_longest))){
			stop_longest = s1.length() - 1;
			start_longest = start;
			longest_frame = 1;
			//System.out.println("d1");
		}
		//System.out.println(start_longest);
		//System.out.println(stop_longest);
		//System.out.println(stop_longest - start_longest);
		//frame 2
		s2 = temp_f2.get_seq();
		curr_aa = "";
		inFrame = false;
		stopFound = false;
		for(int i = 0; i < s2.length(); i++){
			curr_aa = s2.substring(i, i+1);
			if( (curr_aa.equalsIgnoreCase("m")) && !inFrame){
				start=i;
				inFrame = true;
				stopFound = false;
			}
			if( (curr_aa.equals(".")) && inFrame ){
				stop=i;
				inFrame = false;
				stopFound = true;
			}
			if(!inFrame && stopFound){
				if( (stop - start) > (stop_longest - start_longest) ){
					stop_longest = stop;
					start_longest = start;
					longest_frame = 2;
				}
				inFrame = false;
				stopFound = false;
			}
			
		}
		
		if(!stopFound && inFrame && ((s2.length() -1 - start) > (stop_longest - start_longest))){
			stop_longest = s2.length() - 1;
			start_longest = start;
			longest_frame = 2;
		}
		
		//frame 3
		s3 = temp_f3.get_seq();	
		for(int i = 0; i < s3.length(); i++){
			curr_aa = s3.substring(i, i+1);

			if( (curr_aa.equalsIgnoreCase("m")) && !inFrame){
				start=i;
				inFrame = true;
				stopFound = false;

			}
			if( (curr_aa.equals(".")) && inFrame ){
				stop=i;
				inFrame = false;
				stopFound = true;

			}
			if(!inFrame && stopFound){
				if( (stop - start) > (stop_longest - start_longest) ){
					stop_longest = stop;
					start_longest = start;
					longest_frame = 3;
					
				}
				inFrame = false;
				stopFound = false;
			}
			
		}
		
		if(!stopFound && inFrame && ((s3.length() - 1 - start) > (stop_longest - start_longest))){
			stop_longest = s3.length() - 1;
			start_longest = start;
			longest_frame = 3;
		}
		
		//frame 4
		s4 = temp_f4.get_seq();
		curr_aa = "";
		inFrame = false;
		stopFound = false;	
		for(int i = 0; i < s4.length(); i++){
			curr_aa = s4.substring(i, i+1);
			if( (curr_aa.equalsIgnoreCase("m")) && !inFrame){
				start=i;
				inFrame = true;
				stopFound = false;
			}
			if( (curr_aa.equals(".")) && inFrame ){
				stop=i;
				inFrame = false;
				stopFound = true;
			}
			if(!inFrame && stopFound){
				if( (stop - start) > (stop_longest - start_longest) ){
					stop_longest = stop;
					start_longest = start;
					longest_frame = 4;
				}
				inFrame = false;
				stopFound = false;
			}
			
		}
		
		if(!stopFound && inFrame && ((s4.length() - 1 - start) > (stop_longest - start_longest))){
			stop_longest = s4.length() - 1;
			start_longest = start;
			longest_frame = 4;
		}
		
		//frame 5
		s5 = temp_f5.get_seq();
		curr_aa = "";
		inFrame = false;
		stopFound = false;
		for(int i = 0; i < s5.length(); i++){
			curr_aa = s5.substring(i, i+1);
			if( (curr_aa.equalsIgnoreCase("m")) && !inFrame){
				start=i;
				inFrame = true;
				stopFound = false;
			}
			if( (curr_aa.equals(".")) && inFrame ){
				stop=i;
				inFrame = false;
				stopFound = true;
			}
			if(!inFrame && stopFound){
				if( (stop - start) > (stop_longest - start_longest) ){
					stop_longest = stop;
					start_longest = start;
					longest_frame = 5;
				}
				inFrame = false;
				stopFound = false;
			}
			
		}
		
		if(!stopFound && inFrame && ((s5.length() - 1 - start) > (stop_longest - start_longest))){
			stop_longest = s5.length() - 1;
			start_longest = start;
			longest_frame = 5;
		}
		
		/*System.out.println(s0);
		System.out.println(s1);
		System.out.println(s2);
		System.out.println(s3);
		System.out.println(s4);
		System.out.println(s5);*/
		
		//System.out.println(this.tag);
		
		//System.out.println(longest_frame);
		if(longest_frame == 0){
			return_seq.set_seq(s0.substring(start_longest, stop_longest+1));
		}
		if(longest_frame == 1){
			return_seq.set_seq(s1.substring(start_longest, stop_longest+1));
		}
		if(longest_frame == 2){
			return_seq.set_seq(s2.substring(start_longest, stop_longest+1));
		}
		if(longest_frame == 3){
			return_seq.set_seq(s3.substring(start_longest, stop_longest+1));
		}
		if(longest_frame == 4){
			return_seq.set_seq(s4.substring(start_longest, stop_longest+1));
		}
		if(longest_frame == 5){
			return_seq.set_seq(s5.substring(start_longest, stop_longest+1));
		}
		
		return return_seq;
	}
	
}
